**Final Project** Student name: Hongxiao Zheng Netid: F007021 (##) Motivation ![DeLorean DMC-12 in Back to the Future](../final_project_proposal/reference.jpg) The reference image depicts the iconic time-travel device from "Back to the Future," which embodies the theme "Reflections on Time." This device visually combines a sense of nostalgia with futuristic imagination, capturing the interplay between past and future. (##) Feature 1: Parellization with Nanothread/C++17 * Nanothread is used in `Scene::raytrace()` to replace the for-loop with a parallelized version, distributing the workload across CPU cores. * We flattened 2D pixel array into 1D range and used `drjit::parallel_for` to parallelize the rendering process. * To test this feature, we rendered the same scene and compared the performance. The rendering time was reduced from 1m:30s to 13.596s, approximately 6.6x faster. The image quality remained consistent.
Single-threaded Multi-threaded
(##) Feature 2: Basic Denoising: Bilateral Filter with Uniform Variance * A bilateral filter with uniform variance was applied as a post-processing step to denoise rendered images. The filter balances edge preservation with noise reduction, improving visual clarity without blurring important details. * The function `Scene::bilateral_denoise()` was implemented to apply the filter to the rendered image. * To test this feature, we rendered the same scene with and without denoising. The denoised image showed reduction in noise while preserving sharp edges and details. * I tried different kernel sizes and sigma values to find the optimal parameters for the bilateral filter.
Original-4spp Denoised-4spp Original-16spp Denoised-16spp
(##) Task 3: Intel's Open Image Denoise integration * Intel's Open Image Denoise (OIDN) was integrated into the rendering pipeline to provide state-of-the-art AI-based denoising for path-traced images. * We modified `DartsConfig.cmake` to include the necessary OIDN libraries and headers. `ispc` and `tbb` were also installed to support OIDN. Since I failed to force cmake to run git clone with `--resursive` flag, I manually cloned the OIDN repository with `lfs`. * The function `Scene::oidn_denoise()` was implemented to apply OIDN to the rendered image. * We modified `Scene::parse()` to allow setting denoiser type in the JSON file. * To test this feature, we rendered the same scene with and without OIDN denoising. The denoised image showed significant reduction in noise while preserving sharp edges and details. It is particularly effective for low SPP images.
Original-4spp Denoised-4spp Original-16spp Denoised-16spp
(##) Feature 4: Adaptive Sampling with Pixel Variance Estimates * Adaptive sampling was implemented to improve rendering efficiency by allocating computational effort based on pixel variance. The technique stops sampling pixels that meet a variance threshold early, while continuing to refine noisier pixels. * We implemented the function in `Scene::raytrace()`. We accept an `adaptive` boolean flag, a `float` threadhold, `min_samples` and `max_samples` as parameters to the JSON file. The threshold is set to 0.001 by default. * To test this feature, we rendered the same scene with different adaptive sampling settings with denoiser turned off. * Adaptive sampling with `min samples = 16` renders almost the same quality as uniform sampling, but with more defects at edges. | Minimum Samples | Maximum Samples | Time (s) | Total Intersection Tests | |-----------------|-----------------|----------|---------------------------| | 4 | 100 | 11.797 | 67665822 | | 16 | 100 | 13.294 | 80857346 | | 100 | 100 | 13.324 | 92135647 |
Uniform-100spp Adaptive-min4spp-max100spp Adaptive-min16spp-max100spp
* Tested another scene where adaptive sampling is more effective. | Minimum Samples | Maximum Samples | Time (s) | Total Intersection Tests | |-----------------|-----------------|----------|---------------------------| | 4 | 100 | 2.051 | 8484163 | | 16 | 100 | 3.155 | 18193290 | | 100 | 100 | 6.399 | 34850578 |
Uniform-100spp Adaptive-min4spp-max100spp Adaptive-min16spp-max100spp
* We also tested different threshold values for adaptive sampling. In the following tests, `max samples = 100` and `min samples = 16` for adaptive sampling; and `samples = 100` for uniform sampling. * The results showed that a lower threshold led to more samples and longer rendering times, while a higher threshold reduced the number of samples and rendering time. | Threshold | Time (s) | Total Intersection Tests | |-----------|----------|---------------------------| | 0.001 | 13.294 | 80857346 | | 0.005 | 9.876 | 65616106 | | 0.01 | 5.109 | 24931624 |
Uniform Adaptive-threshold0.001 Adaptive-threshold0.005 Adaptive-threshold0.01
(##) Feature 5: Adaptive sampling with Simple Denoising * Adaptive sampling can be combined with the bilateral filter to improve rendering efficiency while maintaining image quality.
Uniform-100spp-no-denoiser Uniform-100spp Adaptive-min4spp-max100spp Adaptive-min16spp-max100spp
(##) Feature 6: Environment Map Emitter (with importance sampling) * Environment map emitter was implemented to simulate light sources with HDRI images. * We implemented `EnvironmentMap` class to load and sample environment maps. We modified parser to allow setting environment map in the JSON file. `PathTracerMIS::trace()` is also updated to sample environment map apart from light sources. * We built a simple scene with a metalic cube to test the environment map emitter. Environment Map Emitter (##) Custom Scene * We downloaded a car model and a HDRI background from the internet and combined them in a scene. We positioned the camera and deleted any unnecessary objects to make rendering more efficient. * We added one area light above and one small area light inside the car since the glass will block any importance sampling. * We used the `path tracer mis` integrator with adaptive sampling and OIDN denoising to render the scene. ```json "sampler": { "type": "independent", "min samples": 16, "max samples": 100, "adaptive": true, "adaptive threshold": 0.005 } ``` Custom scene ```cpp ——————————————————————————————————————————————————————————————————————————————————————————————— Statistics: ——————————————————————————————————————————————————————————————————————————————————————————————— BBH Interior nodes 417819 Leaf nodes 42773 Nodes visited per ray 23034222632 / 69846470 (329.78x) Surfaces per leaf node 375047 / 42773 (8.77x) Geometry Triangles per mesh 375047 / 132 (2841.27x) Integrator Camera rays traced 6291252 Intersections Total intersection tests per ray 15035729926 / 69846470 (215.27x) Triangle intersection tests per hit 15035729926 / 148605508 (101.18x) Memory Triangles 30.69 MiB Scene Materials 25 Surfaces 132 ——————————————————————————————————————————————————————————————————————————————————————————————— Rendering │██████████████████████████████████████████████████████████████████████████│ (31m:03s) ```